package com.songminju.jsong_ioc;

import java.lang.reflect.Field;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import com.songminju.jsong_ioc.loadclass.LoadClassUtil;

class DefaultIOCManager implements IOCManager{
	
	private Map<String,Object> objs = new ConcurrentHashMap<>();
	private Map<Class,String> clToKey = new ConcurrentHashMap<>();
	

	public void put(String key, Object obj) {
		objs.put(key, obj);
		clToKey.put(obj.getClass(), key);
	}

	public Object get(String key) {
		return objs.get(key);
	}

	public Object get(Class<Object> c) {
		String key = clToKey.get(c);
		return key == null?null:objs.get(key);
	}

	public void load(String packageStr, boolean injection, ObjectFilter<Class<Object>> filter,ObjectFilter<Field> injectionFilter) {
		// TODO Auto-generated method stub
		LoadClassUtil classUtil = new LoadClassUtil();
		List<String> list = classUtil.scanClassList(packageStr);
		ClassLoader cl = this.getClass().getClassLoader();
		for(String str:list) {
			try {
				Class c = cl.loadClass(str);
				if( (!c.isInterface()) && filter.pattern(c)) {
					Object obj = c.newInstance();
					this.put(c.getName(), obj);
				}
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		if(injection) {
			Set<String> keys = objs.keySet();
			for(String key:keys) {
				Object obj = objs.get(key);
				Field[] fields = obj.getClass().getFields();
				for(Field f:fields) {
					try {
						if(injectionFilter.pattern(f)) {
							f.setAccessible(true);
							Class c = f.getType();
							Object fieldValue = this.get(c);
							f.set(obj, fieldValue);
						}
					}catch(Exception e) {
						e.printStackTrace();
					}
				}
			}
		}
	}

	@Override
	public Map<String, Object> getAll() {
		// TODO Auto-generated method stub
		return objs;
	}
	
}
